package com.ruoyi.wms.service.impl;

import java.util.List;
import java.util.Date;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.exception.ServiceException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.ruoyi.wms.mapper.WmsOutboundOrderMapper;
import com.ruoyi.wms.domain.WmsOutboundOrder;
import com.ruoyi.wms.service.IWmsOutboundOrderService;
import com.ruoyi.wms.mapper.WmsOutboundOrderDetailMapper;
import com.ruoyi.wms.domain.WmsOutboundOrderDetail;
import com.ruoyi.wms.mapper.WmsInventoryMapper;
import com.ruoyi.wms.domain.WmsInventory;
import com.ruoyi.wms.mapper.WmsInventoryAllocationMapper;
import com.ruoyi.wms.domain.WmsInventoryAllocation;
import com.ruoyi.wms.mapper.WmsOutboundRecordMapper;
import com.ruoyi.wms.domain.WmsOutboundRecord;
import com.ruoyi.wms.service.IWmsInventoryService;
import com.ruoyi.wms.domain.dto.InventoryIncreaseRequest;
import com.ruoyi.wms.domain.dto.InventoryDecreaseRequest;
import com.ruoyi.wms.domain.dto.InventoryIncreaseResponse;
import com.ruoyi.wms.service.IWmsOutboundOrderDetailService;
import com.ruoyi.wms.service.IWmsInventoryAllocationService;
import com.ruoyi.wms.service.IWmsOutboundRecordService;

/**
 * 出库单Service业务层处理
 * 
 * @author ruoyi
 * @date 2024-01-01
 */
@Service
public class WmsOutboundOrderServiceImpl implements IWmsOutboundOrderService 
{
    @Autowired
    private WmsOutboundOrderMapper wmsOutboundOrderMapper;

    @Autowired
    private WmsOutboundOrderDetailMapper wmsOutboundOrderDetailMapper;

    @Autowired
    private WmsInventoryAllocationMapper wmsInventoryAllocationMapper;

    @Autowired
    private WmsInventoryMapper wmsInventoryMapper;

    @Autowired
    private WmsOutboundRecordMapper wmsOutboundRecordMapper;
    
    @Autowired
    private IWmsInventoryService wmsInventoryService;

    @Autowired
    private IWmsOutboundOrderDetailService wmsOutboundOrderDetailService;

    @Autowired
    private IWmsInventoryAllocationService wmsInventoryAllocationService;

    @Autowired
    private IWmsOutboundRecordService wmsOutboundRecordService;

    /**
     * 查询出库单
     * 
     * @param orderId 出库单主键
     * @return 出库单
     */
    @Override
    public WmsOutboundOrder selectWmsOutboundOrderById(Long orderId)
    {
        WmsOutboundOrder order = wmsOutboundOrderMapper.selectWmsOutboundOrderById(orderId);
        if (order != null) {
            // 查询出库单明细
            List<WmsOutboundOrderDetail> detailList = wmsOutboundOrderDetailMapper.selectWmsOutboundOrderDetailByOrderId(orderId);
            order.setDetailList(detailList);
        }
        return order;
    }

    /**
     * 查询出库单列表
     * 
     * @param wmsOutboundOrder 出库单
     * @return 出库单
     */
    @Override
    public List<WmsOutboundOrder> selectWmsOutboundOrderList(WmsOutboundOrder wmsOutboundOrder)
    {
        // 设置租户ID
        wmsOutboundOrder.setTenantId(SecurityUtils.getTenantId());
        return wmsOutboundOrderMapper.selectWmsOutboundOrderList(wmsOutboundOrder);
    }

    /**
     * 新增出库单
     * 
     * @param wmsOutboundOrder 出库单
     * @return 结果
     */
    @Override
    @Transactional
    public int insertWmsOutboundOrder(WmsOutboundOrder wmsOutboundOrder)
    {
        // 设置租户ID和创建信息
        wmsOutboundOrder.setTenantId(SecurityUtils.getTenantId());
        wmsOutboundOrder.setCreateBy(SecurityUtils.getUsername());
        wmsOutboundOrder.setCreateTime(DateUtils.getNowDate());
        
        // 生成出库单号
        if (wmsOutboundOrder.getOrderNo() == null || wmsOutboundOrder.getOrderNo().isEmpty()) {
            String orderNo = generateOrderNo(wmsOutboundOrder.getTenantId(), wmsOutboundOrder.getOrderType());
            wmsOutboundOrder.setOrderNo(orderNo);
        }
        
        // 设置默认状态为待出库
        if (wmsOutboundOrder.getOrderStatus() == null || wmsOutboundOrder.getOrderStatus().isEmpty()) {
            wmsOutboundOrder.setOrderStatus("PENDING"); // 待出库
        }
        
        int result = wmsOutboundOrderMapper.insertWmsOutboundOrder(wmsOutboundOrder);
        
        // 保存出库单明细
        if (result > 0 && wmsOutboundOrder.getDetailList() != null && !wmsOutboundOrder.getDetailList().isEmpty()) {
            for (WmsOutboundOrderDetail detail : wmsOutboundOrder.getDetailList()) {
                detail.setOrderId(wmsOutboundOrder.getOrderId());
                detail.setTenantId(wmsOutboundOrder.getTenantId());
                detail.setCreateBy(SecurityUtils.getUsername());
                detail.setCreateTime(DateUtils.getNowDate());
                detail.setDetailStatus("PENDING"); // 待出库
                detail.setAllocatedQty(BigDecimal.ZERO);
                detail.setPickedQty(BigDecimal.ZERO);
                detail.setShippedQty(BigDecimal.ZERO);
            }
            wmsOutboundOrderDetailMapper.batchInsertWmsOutboundOrderDetail(wmsOutboundOrder.getDetailList());
        }
        
        return result;
    }

    /**
     * 修改出库单
     * 
     * @param wmsOutboundOrder 出库单
     * @return 结果
     */
    @Override
    @Transactional
    public int updateWmsOutboundOrder(WmsOutboundOrder wmsOutboundOrder)
    {
        wmsOutboundOrder.setUpdateBy(SecurityUtils.getUsername());
        wmsOutboundOrder.setUpdateTime(DateUtils.getNowDate());
        
        int result = wmsOutboundOrderMapper.updateWmsOutboundOrder(wmsOutboundOrder);
        
        // 更新出库单明细
        if (result > 0 && wmsOutboundOrder.getDetailList() != null && !wmsOutboundOrder.getDetailList().isEmpty()) {
            // 先删除原有明细
            wmsOutboundOrderDetailMapper.deleteWmsOutboundOrderDetailByOrderId(wmsOutboundOrder.getOrderId());
            
            // 重新插入明细
            for (WmsOutboundOrderDetail detail : wmsOutboundOrder.getDetailList()) {
                detail.setOrderId(wmsOutboundOrder.getOrderId());
                detail.setTenantId(wmsOutboundOrder.getTenantId());
                detail.setUpdateBy(SecurityUtils.getUsername());
                detail.setUpdateTime(DateUtils.getNowDate());
            }
            wmsOutboundOrderDetailMapper.batchInsertWmsOutboundOrderDetail(wmsOutboundOrder.getDetailList());
        }
        
        return result;
    }

    /**
     * 批量删除出库单
     * 
     * @param orderIds 需要删除的出库单主键
     * @return 结果
     */
    @Override
    @Transactional
    public int deleteWmsOutboundOrderByIds(Long[] orderIds)
    {
        // 删除相关的出库记录、库存分配和明细
        for (Long orderId : orderIds) {
            // 删除出库记录
            List<WmsOutboundRecord> recordList = wmsOutboundRecordMapper.selectWmsOutboundRecordByOrderId(orderId);
            if (recordList != null && !recordList.isEmpty()) {
                Long[] recordIds = recordList.stream().map(WmsOutboundRecord::getRecordId).toArray(Long[]::new);
                wmsOutboundRecordMapper.deleteWmsOutboundRecordByIds(recordIds);
            }
            // 删除库存分配记录（通过明细ID删除）
        wmsInventoryAllocationMapper.deleteWmsInventoryAllocationByOrderId(orderId);
            wmsOutboundOrderDetailMapper.deleteWmsOutboundOrderDetailByOrderId(orderId);
        }
        
        return wmsOutboundOrderMapper.deleteWmsOutboundOrderByIds(orderIds);
    }

    /**
     * 删除出库单信息
     * 
     * @param orderId 出库单主键
     * @return 结果
     */
    @Override
    @Transactional
    public int deleteWmsOutboundOrderById(Long orderId)
    {
        // 删除相关的出库记录、库存分配和明细
        // 删除出库记录
        List<WmsOutboundRecord> recordList = wmsOutboundRecordMapper.selectWmsOutboundRecordByOrderId(orderId);
        if (recordList != null && !recordList.isEmpty()) {
            Long[] recordIds = recordList.stream().map(WmsOutboundRecord::getRecordId).toArray(Long[]::new);
            wmsOutboundRecordMapper.deleteWmsOutboundRecordByIds(recordIds);
        }
        // 删除库存分配记录（通过明细ID删除）
        wmsInventoryAllocationMapper.deleteWmsInventoryAllocationByOrderId(orderId);
        wmsOutboundOrderDetailMapper.deleteWmsOutboundOrderDetailByOrderId(orderId);
        
        return wmsOutboundOrderMapper.deleteWmsOutboundOrderById(orderId);
    }

    /**
     * 库存分配
     * 
     * @param orderId 出库单ID
     * @return 结果
     */
    @Override
    @Transactional
    public int allocateInventory(Long orderId)
    {
        WmsOutboundOrder order = wmsOutboundOrderMapper.selectWmsOutboundOrderById(orderId);
        if (order == null) {
            throw new ServiceException("出库单不存在");
        }
        
        if (!"PENDING".equals(order.getOrderStatus())) {
            throw new ServiceException("只有待出库状态的出库单才能进行库存分配");
        }
        
        List<WmsOutboundOrderDetail> detailList = wmsOutboundOrderDetailMapper.selectWmsOutboundOrderDetailByOrderId(orderId);
        if (detailList == null || detailList.isEmpty()) {
            throw new ServiceException("出库单明细不存在");
        }
        
        boolean allAllocated = true;
        
        for (WmsOutboundOrderDetail detail : detailList) {
            if (!"PENDING".equals(detail.getDetailStatus())) {
                continue; // 跳过非待出库状态的明细
            }
            
            // 查询可用库存（按FIFO排序）
            WmsInventory queryCondition = new WmsInventory();
            queryCondition.setTenantId(order.getTenantId());
            queryCondition.setOwnerId(order.getOwnerId());
            queryCondition.setWarehouseId(order.getWarehouseId());
            queryCondition.setItemId(detail.getItemId());
            queryCondition.setSupplierId(detail.getSupplierId());
            queryCondition.setUnit(detail.getUnit());
            
            List<WmsInventory> inventoryList = wmsInventoryMapper.selectInventoryListForDecrease(
                queryCondition.getTenantId(),
                queryCondition.getOwnerId(),
                queryCondition.getWarehouseId(),
                queryCondition.getItemId(),
                "NORMAL", // 正常库存状态
                null, // 库位ID
                queryCondition.getSupplierId(),
                null, // 批次号
                null  // 容器号
            );
            
            BigDecimal remainingQty = detail.getRequiredQty();
            BigDecimal allocatedQty = BigDecimal.ZERO;
            
            for (WmsInventory inventory : inventoryList) {
                if (remainingQty.compareTo(BigDecimal.ZERO) <= 0) {
                    break;
                }
                
                BigDecimal availableQty = inventory.getAvailableQty();
                if (availableQty.compareTo(BigDecimal.ZERO) <= 0) {
                    continue;
                }
                
                BigDecimal allocationQty = remainingQty.min(availableQty);
                
                // 按照设计文档要求：先调用增加库存API生成已分配库存数据，再调用减少库存API减去原库存数据
                
                // 1. 调用增加库存API生成已分配的库存数据
                InventoryIncreaseRequest increaseRequest = new InventoryIncreaseRequest();
                increaseRequest.setTenantId(order.getTenantId());
                increaseRequest.setOwnerId(order.getOwnerId());
                increaseRequest.setWarehouseId(order.getWarehouseId());
                increaseRequest.setItemId(detail.getItemId());
                increaseRequest.setIncreaseQty(allocationQty);
                // 使用原库存的单位，而不是出库单明细的单位
                increaseRequest.setUnit(inventory.getUnit());
                increaseRequest.setInventoryStatus("ALLOCATED"); // 已分配状态
                increaseRequest.setLocationId(inventory.getLocationId());
                // 使用原库存的供应商ID，而不是出库单明细的供应商ID
                increaseRequest.setSupplierId(inventory.getSupplierId());
                increaseRequest.setBatchNo(inventory.getBatchNo());
                increaseRequest.setContainerNo(inventory.getContainerNo());
                increaseRequest.setProductionDate(inventory.getProductionDate());
                increaseRequest.setExpirationDate(inventory.getExpirationDate());
                increaseRequest.setOperationType("ALLOCATION");
                increaseRequest.setRemark("出库单分配-单号:" + order.getOrderNo());
                
                InventoryIncreaseResponse increaseResponse = wmsInventoryService.increaseInventory(increaseRequest);
                
                // 2. 调用减少库存API减去原库存数据
                InventoryDecreaseRequest decreaseRequest = new InventoryDecreaseRequest();
                decreaseRequest.setTenantId(order.getTenantId());
                decreaseRequest.setOwnerId(order.getOwnerId());
                decreaseRequest.setWarehouseId(order.getWarehouseId());
                decreaseRequest.setItemId(detail.getItemId());
                decreaseRequest.setDecreaseQty(allocationQty);
                // 使用原库存的单位，确保数据一致性
                decreaseRequest.setUnit(inventory.getUnit());
                decreaseRequest.setInventoryStatus("NORMAL"); // 正常状态
                decreaseRequest.setLocationId(inventory.getLocationId());
                // 使用原库存的供应商ID，确保数据一致性
                decreaseRequest.setSupplierId(inventory.getSupplierId());
                decreaseRequest.setBatchNo(inventory.getBatchNo());
                decreaseRequest.setContainerNo(inventory.getContainerNo());
                decreaseRequest.setOperationType("ALLOCATION");
                decreaseRequest.setRemark("出库单分配-单号:" + order.getOrderNo());
                
                wmsInventoryService.decreaseInventory(decreaseRequest);
                
                // 3. 创建库存分配记录，关联到新生成的已分配库存
                WmsInventoryAllocation allocation = new WmsInventoryAllocation();
                allocation.setTenantId(order.getTenantId());
                allocation.setOrderId(order.getOrderId()); // 设置出库单ID
                allocation.setDetailId(detail.getDetailId());
                allocation.setInventoryId(increaseResponse.getInventoryId()); // 使用新生成的已分配库存ID
                allocation.setWarehouseId(order.getWarehouseId()); // 设置仓库ID
                allocation.setAllocatedQty(allocationQty);
                allocation.setPickedQty(BigDecimal.ZERO);
                // shippedQty字段已移除，出库数量等于拣货数量
                allocation.setAllocationStatus("ALLOCATED"); // 已分配
                // 从原库存数据中获取字段值
                allocation.setSupplierId(inventory.getSupplierId()); // 从原库存获取供应商ID
                allocation.setUnit(inventory.getUnit()); // 从原库存获取单位
                allocation.setProductionDate(inventory.getProductionDate()); // 从原库存获取生产日期
                allocation.setExpiryDate(inventory.getExpirationDate()); // 从原库存获取过期日期
                // 分配时间使用 createTime 字段记录
                allocation.setCreateBy(SecurityUtils.getUsername());
                allocation.setCreateTime(DateUtils.getNowDate());
                allocation.setUpdateBy(SecurityUtils.getUsername());
                allocation.setUpdateTime(DateUtils.getNowDate());
                
                wmsInventoryAllocationMapper.insertWmsInventoryAllocation(allocation);
                
                allocatedQty = allocatedQty.add(allocationQty);
                remainingQty = remainingQty.subtract(allocationQty);
            }
            
            // 更新明细的已分配数量和状态
            detail.setAllocatedQty(allocatedQty);
            if (allocatedQty.compareTo(detail.getRequiredQty()) >= 0) {
                detail.setDetailStatus("ALLOCATED"); // 已分配
            } else if (allocatedQty.compareTo(BigDecimal.ZERO) > 0) {
                detail.setDetailStatus("PARTIAL_ALLOCATED"); // 部分分配
                allAllocated = false;
            } else {
                detail.setDetailStatus("ALLOCATION_FAILED"); // 分配失败
                allAllocated = false;
            }
            
            wmsOutboundOrderDetailMapper.updateWmsOutboundOrderDetail(detail);
        }
        
        // 重新检查所有明细的分配状态，确定出库单最终状态
        List<WmsOutboundOrderDetail> allDetails = wmsOutboundOrderDetailMapper.selectWmsOutboundOrderDetailByOrderId(orderId);
        boolean hasAllocated = false;
        boolean hasPartialAllocated = false;
        boolean hasAllocationFailed = false;
        boolean allFullyAllocated = true;
        
        for (WmsOutboundOrderDetail detail : allDetails) {
            if ("ALLOCATED".equals(detail.getDetailStatus())) {
                hasAllocated = true;
            } else if ("PARTIAL_ALLOCATED".equals(detail.getDetailStatus())) {
                hasPartialAllocated = true;
                allFullyAllocated = false;
            } else if ("ALLOCATION_FAILED".equals(detail.getDetailStatus())) {
                hasAllocationFailed = true;
                allFullyAllocated = false;
            } else {
                allFullyAllocated = false;
            }
        }
        
        // 更新出库单状态
        WmsOutboundOrder updateOrder = new WmsOutboundOrder();
        updateOrder.setOrderId(orderId);
        
        if (allFullyAllocated && hasAllocated) {
            updateOrder.setOrderStatus("ALLOCATED"); // 完全分配
        } else if (hasAllocated || hasPartialAllocated) {
            updateOrder.setOrderStatus("PARTIAL_ALLOCATED"); // 部分分配
        } else if (hasAllocationFailed) {
            updateOrder.setOrderStatus("ALLOCATION_FAILED"); // 分配失败
        } else {
            updateOrder.setOrderStatus("PENDING"); // 保持待处理状态
        }
        
        wmsOutboundOrderMapper.updateWmsOutboundOrder(updateOrder);
        
        return 1;
    }

    /**
     * 开始拣货
     * 
     * @param orderId 出库单ID
     * @return 结果
     */
    @Override
    @Transactional
    public int startPicking(Long orderId)
    {
        WmsOutboundOrder order = wmsOutboundOrderMapper.selectWmsOutboundOrderById(orderId);
        if (order == null) {
            throw new ServiceException("出库单不存在");
        }
        
        if (!"ALLOCATED".equals(order.getOrderStatus()) && !"PARTIAL_ALLOCATED".equals(order.getOrderStatus())) {
            throw new ServiceException("只有已分配或部分分配状态的出库单才能开始拣货");
        }
        
        List<WmsInventoryAllocation> allocationList = wmsInventoryAllocationMapper.selectWmsInventoryAllocationByOrderId(orderId);
        if (allocationList == null || allocationList.isEmpty()) {
            throw new ServiceException("库存分配记录不存在");
        }
        
        // 更新出库单状态为拣货中
        WmsOutboundOrder updateOrder = new WmsOutboundOrder();
        updateOrder.setOrderId(orderId);
        updateOrder.setOrderStatus("PICKING"); // 拣货中
        wmsOutboundOrderMapper.updateWmsOutboundOrder(updateOrder);
        
        // 更新分配状态为拣货中
        for (WmsInventoryAllocation allocation : allocationList) {
            if ("ALLOCATED".equals(allocation.getAllocationStatus())) {
                allocation.setAllocationStatus("PICKING"); // 拣货中
                wmsInventoryAllocationMapper.updateWmsInventoryAllocation(allocation);
            }
        }
        
        // 更新明细状态为拣货中
        List<WmsOutboundOrderDetail> detailList = wmsOutboundOrderDetailMapper.selectWmsOutboundOrderDetailByOrderId(orderId);
        for (WmsOutboundOrderDetail detail : detailList) {
            if ("ALLOCATED".equals(detail.getDetailStatus()) || "PARTIAL_ALLOCATED".equals(detail.getDetailStatus())) {
                detail.setDetailStatus("PICKING"); // 拣货中
                wmsOutboundOrderDetailMapper.updateWmsOutboundOrderDetail(detail);
            }
        }
        
        return 1;
    }

    /**
     * 确认拣货
     * 
     * @param orderId 出库单ID
     * @return 结果
     */
    @Override
    @Transactional
    public int confirmPicking(Long orderId)
    {
        WmsOutboundOrder order = wmsOutboundOrderMapper.selectWmsOutboundOrderById(orderId);
        if (order == null) {
            throw new ServiceException("出库单不存在");
        }
        
        if (!"PICKING".equals(order.getOrderStatus())) {
            throw new ServiceException("只有拣货中状态的出库单才能进行拣货确认");
        }
        
        List<WmsInventoryAllocation> allocationList = wmsInventoryAllocationMapper.selectWmsInventoryAllocationByOrderId(orderId);
        if (allocationList == null || allocationList.isEmpty()) {
            throw new ServiceException("库存分配记录不存在");
        }
        
        // 更新分配状态为已拣货
        for (WmsInventoryAllocation allocation : allocationList) {
            if ("PICKING".equals(allocation.getAllocationStatus())) {
                // 获取已分配的库存信息
                WmsInventory allocatedInventory = wmsInventoryMapper.selectWmsInventoryById(allocation.getInventoryId());
                
                // 1. 先调用库存增加API，新增一条状态为已拣货的库存数据
                InventoryIncreaseRequest increaseRequest = new InventoryIncreaseRequest();
                increaseRequest.setTenantId(order.getTenantId());
                increaseRequest.setOwnerId(order.getOwnerId());
                increaseRequest.setWarehouseId(order.getWarehouseId());
                increaseRequest.setItemId(allocatedInventory.getItemId());
                increaseRequest.setIncreaseQty(allocation.getAllocatedQty());
                increaseRequest.setUnit(allocatedInventory.getUnit());
                increaseRequest.setInventoryStatus("PICKED"); // 已拣货状态
                increaseRequest.setLocationId(allocatedInventory.getLocationId());
                increaseRequest.setSupplierId(allocatedInventory.getSupplierId());
                increaseRequest.setBatchNo(allocatedInventory.getBatchNo());
                increaseRequest.setContainerNo(allocatedInventory.getContainerNo());
                increaseRequest.setProductionDate(allocatedInventory.getProductionDate());
                increaseRequest.setExpirationDate(allocatedInventory.getExpirationDate());
                increaseRequest.setOperationType("PICKING");
                increaseRequest.setRemark("拣货确认-单号:" + order.getOrderNo());
                
                InventoryIncreaseResponse increaseResponse = wmsInventoryService.increaseInventory(increaseRequest);
                
                // 2. 先更新库存分配记录，将inventoryId指向新创建的PICKED状态库存，避免级联删除
                allocation.setInventoryId(increaseResponse.getInventoryId()); // 更新为新创建的PICKED状态库存ID
                allocation.setPickedQty(allocation.getAllocatedQty());
                allocation.setAllocationStatus("PICKED"); // 已拣货
                // 拣货时间使用 updateTime 字段记录
                
                wmsInventoryAllocationMapper.updateWmsInventoryAllocation(allocation);
                
                // 3. 然后调用库存减少API，将状态为已分配的库存数据做扣减
                InventoryDecreaseRequest decreaseRequest = new InventoryDecreaseRequest();
                decreaseRequest.setTenantId(order.getTenantId());
                decreaseRequest.setOwnerId(order.getOwnerId());
                decreaseRequest.setWarehouseId(order.getWarehouseId());
                decreaseRequest.setItemId(allocatedInventory.getItemId());
                decreaseRequest.setDecreaseQty(allocation.getAllocatedQty());
                decreaseRequest.setUnit(allocatedInventory.getUnit());
                decreaseRequest.setInventoryStatus("ALLOCATED"); // 已分配状态
                decreaseRequest.setLocationId(allocatedInventory.getLocationId());
                decreaseRequest.setSupplierId(allocatedInventory.getSupplierId());
                decreaseRequest.setBatchNo(allocatedInventory.getBatchNo());
                decreaseRequest.setContainerNo(allocatedInventory.getContainerNo());
                decreaseRequest.setOperationType("PICKING");
                decreaseRequest.setRemark("拣货确认-单号:" + order.getOrderNo());
                
                wmsInventoryService.decreaseInventory(decreaseRequest);
            }
        }
        
        // 更新明细状态
        List<WmsOutboundOrderDetail> detailList = wmsOutboundOrderDetailMapper.selectWmsOutboundOrderDetailByOrderId(orderId);
        for (WmsOutboundOrderDetail detail : detailList) {
            if ("PICKING".equals(detail.getDetailStatus())) {
                // 完成拣货
                detail.setPickedQty(detail.getAllocatedQty());
                detail.setDetailStatus("PICKED"); // 已拣货
                
                wmsOutboundOrderDetailMapper.updateWmsOutboundOrderDetail(detail);
            }
        }
        
        // 更新出库单状态为已拣货
        WmsOutboundOrder updateOrder = new WmsOutboundOrder();
        updateOrder.setOrderId(orderId);
        updateOrder.setOrderStatus("PICKED"); // 已拣货
        wmsOutboundOrderMapper.updateWmsOutboundOrder(updateOrder);
        
        return 1;
    }

    /**
     * 确认出库
     * 
     * @param orderId 出库单ID
     * @return 结果
     */
    @Override
    @Transactional
    public int confirmOutbound(Long orderId)
    {
        WmsOutboundOrder order = wmsOutboundOrderMapper.selectWmsOutboundOrderById(orderId);
        if (order == null) {
            throw new ServiceException("出库单不存在");
        }
        
        if (!"PICKED".equals(order.getOrderStatus())) {
            throw new ServiceException("只有已拣货状态的出库单才能进行出库确认");
        }
        
        List<WmsInventoryAllocation> allocationList = wmsInventoryAllocationMapper.selectWmsInventoryAllocationByOrderId(orderId);
        if (allocationList == null || allocationList.isEmpty()) {
            throw new ServiceException("库存分配记录不存在");
        }
        
        for (WmsInventoryAllocation allocation : allocationList) {
            if ("PICKED".equals(allocation.getAllocationStatus())) {
                // 先更新为出库中状态
                allocation.setAllocationStatus("SHIPPING"); // 出库中
                wmsInventoryAllocationMapper.updateWmsInventoryAllocation(allocation);
                
                // 完成出库，更新为已完成状态
                allocation.setAllocationStatus("COMPLETED"); // 已完成
                // 出库时间使用 updateTime 字段记录
                
                wmsInventoryAllocationMapper.updateWmsInventoryAllocation(allocation);
                
                // 获取库存信息以填充完整的减少请求
                WmsInventory allocatedInventory = wmsInventoryMapper.selectWmsInventoryById(allocation.getInventoryId());
                
                // 调用减少库存API减少已拣货的库存（实际出库）
                InventoryDecreaseRequest decreaseRequest = new InventoryDecreaseRequest();
                decreaseRequest.setTenantId(order.getTenantId());
                decreaseRequest.setOwnerId(order.getOwnerId());
                decreaseRequest.setWarehouseId(order.getWarehouseId());
                decreaseRequest.setItemId(allocatedInventory.getItemId());
                decreaseRequest.setDecreaseQty(allocation.getPickedQty());
                decreaseRequest.setUnit(allocatedInventory.getUnit());
                decreaseRequest.setInventoryStatus("PICKED"); // 已拣货状态
                decreaseRequest.setLocationId(allocatedInventory.getLocationId());
                decreaseRequest.setSupplierId(allocatedInventory.getSupplierId());
                decreaseRequest.setBatchNo(allocatedInventory.getBatchNo());
                decreaseRequest.setContainerNo(allocatedInventory.getContainerNo());
                decreaseRequest.setOperationType("OUTBOUND");
                decreaseRequest.setRemark("出库确认-单号:" + order.getOrderNo());
                
                wmsInventoryService.decreaseInventory(decreaseRequest);
                
                // 创建出库记录
                WmsOutboundRecord record = new WmsOutboundRecord();
                record.setTenantId(order.getTenantId());
                record.setOrderId(orderId);
                record.setDetailId(allocation.getDetailId());
                record.setAllocationId(allocation.getAllocationId());

                record.setWarehouseId(order.getWarehouseId()); // 设置仓库ID
                record.setLocationId(allocatedInventory.getLocationId()); // 设置库位ID
                record.setItemId(allocatedInventory.getItemId()); // 设置商品ID
                record.setSupplierId(allocatedInventory.getSupplierId()); // 设置供应商ID
                record.setBatchNo(allocatedInventory.getBatchNo()); // 设置批次号
                record.setContainerNo(allocatedInventory.getContainerNo()); // 设置容器号
                record.setUnit(allocatedInventory.getUnit()); // 设置单位
                record.setProductionDate(allocatedInventory.getProductionDate()); // 设置生产日期
                record.setExpiryDate(allocatedInventory.getExpirationDate()); // 设置过期日期
                record.setOutboundQty(allocation.getPickedQty());
                record.setOutboundTime(DateUtils.getNowDate());
                record.setOperator(SecurityUtils.getUsername());
                record.setCreateBy(SecurityUtils.getUsername());
                record.setCreateTime(DateUtils.getNowDate());
                
                wmsOutboundRecordMapper.insertWmsOutboundRecord(record);
            }
        }
        
        // 更新明细状态
        List<WmsOutboundOrderDetail> detailList = wmsOutboundOrderDetailMapper.selectWmsOutboundOrderDetailByOrderId(orderId);
        boolean allShipped = true;
        boolean anyShipped = false;
        
        for (WmsOutboundOrderDetail detail : detailList) {
            if ("PICKED".equals(detail.getDetailStatus())) {
                detail.setShippedQty(detail.getPickedQty());
                detail.setDetailStatus("SHIPPED"); // 已出库
                anyShipped = true;
                
                wmsOutboundOrderDetailMapper.updateWmsOutboundOrderDetail(detail);
            } else if (!"SHIPPED".equals(detail.getDetailStatus()) && !"CANCELLED".equals(detail.getDetailStatus())) {
                allShipped = false;
            }
        }
        
        // 根据明细状态确定出库单状态
        String orderStatus;
        if (allShipped && anyShipped) {
            orderStatus = "SHIPPED"; // 完成出库
        } else if (anyShipped) {
            orderStatus = "PARTIAL_SHIPPED"; // 部分出库
        } else {
            orderStatus = order.getOrderStatus(); // 保持原状态
        }
        
        // 更新出库单状态和实际出库日期
        order.setOrderStatus(orderStatus);
        order.setActualDate(DateUtils.getNowDate());
        wmsOutboundOrderMapper.updateWmsOutboundOrder(order);
        
        return 1;
    }

    /**
     * 取消出库单
     * 
     * @param orderId 出库单ID
     * @return 结果
     */
    @Override
    @Transactional
    public int cancelOutboundOrder(Long orderId)
    {
        WmsOutboundOrder order = wmsOutboundOrderMapper.selectWmsOutboundOrderById(orderId);
        if (order == null) {
            throw new ServiceException("出库单不存在");
        }
        
        if ("SHIPPED".equals(order.getOrderStatus()) || "CANCELLED".equals(order.getOrderStatus())) {
            throw new ServiceException("已出库或已取消的出库单不能再次取消");
        }
        
        // 释放已分配的库存
        List<WmsInventoryAllocation> allocationList = wmsInventoryAllocationMapper.selectWmsInventoryAllocationByOrderId(orderId);
        if (allocationList != null && !allocationList.isEmpty()) {
            for (WmsInventoryAllocation allocation : allocationList) {
                // 处理所有非取消状态的分配记录
                if (!"CANCELLED".equals(allocation.getAllocationStatus())) {
                    // 获取已分配的库存信息
                    WmsInventory allocatedInventory = wmsInventoryMapper.selectWmsInventoryById(allocation.getInventoryId());
                    
                    // 根据分配状态确定要减少的库存状态和数量
                    String inventoryStatusToDecrease;
                    BigDecimal qtyToDecrease;
                    
                    if ("ALLOCATED".equals(allocation.getAllocationStatus()) || "PICKING".equals(allocation.getAllocationStatus())) {
                        // 已分配或拣货中状态：减少ALLOCATED状态库存
                        inventoryStatusToDecrease = "ALLOCATED";
                        qtyToDecrease = allocation.getAllocatedQty();
                    } else if ("PICKED".equals(allocation.getAllocationStatus())) {
                        // 拣货完成状态：减少PICKED状态库存
                        inventoryStatusToDecrease = "PICKED";
                        qtyToDecrease = allocation.getPickedQty();
                    } else {
                        // 其他状态跳过处理
                        continue;
                    }
                    
                    // 1. 减少对应状态的库存
                    InventoryDecreaseRequest decreaseRequest = new InventoryDecreaseRequest();
                    decreaseRequest.setTenantId(order.getTenantId());
                    decreaseRequest.setOwnerId(order.getOwnerId());
                    decreaseRequest.setWarehouseId(order.getWarehouseId());
                    decreaseRequest.setItemId(allocatedInventory.getItemId());
                    decreaseRequest.setDecreaseQty(qtyToDecrease);
                    decreaseRequest.setUnit(allocatedInventory.getUnit());
                    decreaseRequest.setInventoryStatus(inventoryStatusToDecrease);
                    decreaseRequest.setLocationId(allocatedInventory.getLocationId());
                    decreaseRequest.setSupplierId(allocatedInventory.getSupplierId());
                    decreaseRequest.setBatchNo(allocatedInventory.getBatchNo());
                    decreaseRequest.setContainerNo(allocatedInventory.getContainerNo());
                    decreaseRequest.setOperationType("CANCEL");
                    decreaseRequest.setRemark("取消出库单-单号:" + order.getOrderNo());
                    
                    wmsInventoryService.decreaseInventory(decreaseRequest);
                    
                    // 2. 增加正常库存
                    InventoryIncreaseRequest increaseRequest = new InventoryIncreaseRequest();
                    increaseRequest.setTenantId(order.getTenantId());
                    increaseRequest.setOwnerId(order.getOwnerId());
                    increaseRequest.setWarehouseId(order.getWarehouseId());
                    increaseRequest.setItemId(allocatedInventory.getItemId());
                    increaseRequest.setIncreaseQty(qtyToDecrease);
                    increaseRequest.setUnit(allocatedInventory.getUnit());
                    increaseRequest.setInventoryStatus("NORMAL"); // 正常状态
                    increaseRequest.setLocationId(allocatedInventory.getLocationId());
                    increaseRequest.setSupplierId(allocatedInventory.getSupplierId());
                    increaseRequest.setBatchNo(allocatedInventory.getBatchNo());
                    increaseRequest.setContainerNo(allocatedInventory.getContainerNo());
                    increaseRequest.setProductionDate(allocatedInventory.getProductionDate());
                    increaseRequest.setExpirationDate(allocatedInventory.getExpirationDate());
                    increaseRequest.setOperationType("CANCEL");
                    increaseRequest.setRemark("取消出库单-单号:" + order.getOrderNo());
                    
                    wmsInventoryService.increaseInventory(increaseRequest);
                    
                    // 3. 更新分配记录状态为已取消
                    allocation.setAllocationStatus("CANCELLED");
                    wmsInventoryAllocationMapper.updateWmsInventoryAllocation(allocation);
                }
            }
        }
        
        // 更新明细状态
        List<WmsOutboundOrderDetail> detailList = wmsOutboundOrderDetailMapper.selectWmsOutboundOrderDetailByOrderId(orderId);
        if (detailList != null && !detailList.isEmpty()) {
            for (WmsOutboundOrderDetail detail : detailList) {
                if (!"CANCELLED".equals(detail.getDetailStatus())) {
                    detail.setDetailStatus("CANCELLED"); // 已取消
                    detail.setAllocatedQty(BigDecimal.ZERO);
                    detail.setPickedQty(BigDecimal.ZERO);
                    detail.setShippedQty(BigDecimal.ZERO);
                    
                    wmsOutboundOrderDetailMapper.updateWmsOutboundOrderDetail(detail);
                }
            }
        }
        
        // 更新出库单状态
        order.setOrderStatus("CANCELLED"); // 已取消
        wmsOutboundOrderMapper.updateWmsOutboundOrder(order);
        
        return 1;
    }

    /**
     * 根据出库单号查询出库单
     * 
     * @param orderNo 出库单号
     * @param tenantId 租户ID
     * @return 出库单
     */
    @Override
    public WmsOutboundOrder selectWmsOutboundOrderByOrderNo(String orderNo, Long tenantId)
    {
        return wmsOutboundOrderMapper.selectWmsOutboundOrderByOrderNo(orderNo, tenantId);
    }

    /**
     * 生成出库单号
     * 
     * @param tenantId 租户ID
     * @param orderType 出库类型
     * @return 出库单号
     */
    @Override
    public String generateOrderNo(Long tenantId, String orderType)
    {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
        String dateStr = sdf.format(new Date());
        
        String prefix = "OUT";
        if ("SALES".equals(orderType)) {
            prefix = "SALE"; // 销售出库
        } else if ("TRANSFER".equals(orderType)) {
            prefix = "TRAN"; // 调拨出库
        } else if ("PRODUCTION".equals(orderType)) {
            prefix = "PROD"; // 生产出库
        } else if ("RETURN".equals(orderType)) {
            prefix = "RETU"; // 退货出库
        }
        
        return wmsOutboundOrderMapper.generateOrderNo(tenantId, orderType);
    }
}